home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / libs / libelf-0.5 / libelf-0 / libelf-0.5.2 / getdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-19  |  3.5 KB  |  153 lines

  1. /*
  2. getdata.c - implementation of the elf_getdata(3) function.
  3. Copyright (C) 1995 Michael Riepe <riepe@ifwsn4.ifw.uni-hannover.de>
  4.  
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9.  
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #include <private.h>
  21.  
  22. static Elf_Data*
  23. _elf32_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) {
  24.     Elf_Data src, dst;
  25.     size_t fsize, msize;
  26.     int flag = 0;
  27.  
  28.     src = dst = sd->sd_data;
  29.     src.d_version = elf->e_version;
  30.     fsize = _fsize32(src.d_version, src.d_type);
  31.     elf_assert(fsize);
  32.     msize = _msize32(dst.d_version, src.d_type);
  33.     elf_assert(msize);
  34.     if (fsize != msize) {
  35.     dst.d_size = (dst.d_size / fsize) * msize;
  36.     }
  37.  
  38.     elf_assert(elf->e_data);
  39.     if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
  40.     dst.d_buf = elf->e_data + scn->s_offset;
  41.     }
  42.     else if (!(dst.d_buf = malloc(dst.d_size))) {
  43.     seterr(ERROR_MEM_SCNDATA);
  44.     return NULL;
  45.     }
  46.     else {
  47.     flag |= 1;
  48.     }
  49.  
  50.     if (elf->e_rawdata) {
  51.     src.d_buf = elf->e_rawdata + scn->s_offset;
  52.     }
  53.     else {
  54.     if (src.d_size <= dst.d_size) {
  55.         src.d_buf = dst.d_buf;
  56.     }
  57.     else if (!(src.d_buf = malloc(src.d_size))) {
  58.         seterr(ERROR_IO_2BIG);
  59.         goto fail;
  60.     }
  61.     else {
  62.         flag |= 2;
  63.     }
  64.  
  65.     if (!_elf_read(elf, src.d_buf, scn->s_offset, src.d_size)) {
  66.         goto fail;
  67.     }
  68.     }
  69.  
  70.     if (elf32_xlatetom(&dst, &src, elf->e_encoding)) {
  71.     sd->sd_memdata = (char*)dst.d_buf;
  72.     sd->sd_data = dst;
  73.     if (flag & 2) {
  74.         free(src.d_buf);
  75.     }
  76.     if (flag & 1) {
  77.         sd->sd_free_data = 1;
  78.     }
  79.     else {
  80.         elf->e_cooked = 1;
  81.     }
  82.     return (Elf_Data*)sd;
  83.     }
  84.  
  85. fail:
  86.     if (flag & 2) {
  87.     free(src.d_buf);
  88.     }
  89.     if (flag & 1) {
  90.     free(dst.d_buf);
  91.     }
  92.     return NULL;
  93. }
  94.  
  95. Elf_Data*
  96. elf_getdata(Elf_Scn *scn, Elf_Data *data) {
  97.     Scn_Data *sd = (Scn_Data*)data;
  98.     Elf *elf;
  99.  
  100.     if (!scn) {
  101.     return NULL;
  102.     }
  103.     elf_assert(scn->s_magic == SCN_MAGIC);
  104.     if (scn->s_index == SHN_UNDEF) {
  105.     seterr(ERROR_NULLSCN);
  106.     }
  107.     else if (sd) {
  108.     if (sd->sd_scn == scn) {
  109.         /*
  110.          * sd_link allocated by elf_newdata().
  111.          */
  112.         return (Elf_Data*)sd->sd_link;
  113.     }
  114.     seterr(ERROR_SCNDATAMISMATCH);
  115.     }
  116.     else if ((sd = scn->s_data_1)) {
  117.     elf = scn->s_elf;
  118.     elf_assert(elf);
  119.     elf_assert(elf->e_magic == ELF_MAGIC);
  120.     if (sd->sd_freeme) {
  121.         /* allocated by elf_newdata() */
  122.         return (Elf_Data*)sd;
  123.     }
  124.     else if (scn->s_type == SHT_NULL) {
  125.         seterr(ERROR_NULLSCN);
  126.     }
  127.     else if (sd->sd_memdata) {
  128.         /* already cooked */
  129.         return (Elf_Data*)sd;
  130.     }
  131.     else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
  132.         seterr(ERROR_OUTSIDE);
  133.     }
  134.     else if (scn->s_type == SHT_NOBITS || !scn->s_size) {
  135.         /* no data to read */
  136.         return (Elf_Data*)sd;
  137.     }
  138.     else if (scn->s_offset + scn->s_size > elf->e_size) {
  139.         seterr(ERROR_TRUNC_SCN);
  140.     }
  141.     else if (elf->e_class == ELFCLASS32) {
  142.         return _elf32_cook_scn(elf, scn, sd);
  143.     }
  144.     else if (valid_class(elf->e_class)) {
  145.         seterr(ERROR_UNIMPLEMENTED);
  146.     }
  147.     else {
  148.         seterr(ERROR_UNKNOWN_CLASS);
  149.     }
  150.     }
  151.     return NULL;
  152. }
  153.